package microcontroler;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.TooManyListenersException;

import gnu.io.CommPortIdentifier;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import gnu.io.UnsupportedCommOperationException;

public class SerialPortConnector {
	static InputStream input;
	static OutputStream output;

	public enum Light {
		ROOM_LIGHT, KITCHEN_LIGHT, BATHROOM_LIGHT
	}
	
	private static final int TIME_OUT = 2000;

	private SerialPort port;

	private static final String SERIAL_PORT = "COM3";
	private static final int BAUD_RATE = 9600;

	private boolean alarm = false;

	public static void main(String[] args) throws Exception {
		SerialPortConnector spc = new SerialPortConnector(SERIAL_PORT,
				BAUD_RATE);
		spc.toogleLight(Light.KITCHEN_LIGHT);
		spc.setLine(2);
		
		//jak dasz spc.close to port zostanie zamknięty i wszystko zgaśnie dlatego
		//pewnie nie bedziesz z tego korzystał
		//spc.close();
	}

	/**
	 * Konstruuje klasę SerialPortConnector.
	 * 
	 * @param port_id
	 *            identyfikator portu
	 * @param baudRate
	 *            baud rate
	 */
	public SerialPortConnector(String port_name, int baudRate) {
		try {
			// pobiera identyfikator na podstawie jego nazwy
			CommPortIdentifier portId = CommPortIdentifier
					.getPortIdentifier(port_name);

			// otworzenie portu
			port = (SerialPort) portId.open("serial talk", TIME_OUT);

			// inicjalizacja wejścia i wyjścia
			input = port.getInputStream();
			output = port.getOutputStream();

			// ustawienie dodatkowych parametrów
			port.setSerialPortParams(baudRate, SerialPort.DATABITS_8,
					SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);

			port.addEventListener(new SerialPortEventListener() {
				@Override
				public void serialEvent(SerialPortEvent event) {
					if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
						try {
							int available = input.available();
							byte chunk[] = new byte[available];
							input.read(chunk, 0, available);

							String s = new String(chunk);

							if (s.equals("A")) {
								alarm = true;
							} else {
								alarm = false;
							}
						} catch (Exception e) {
							e.printStackTrace();
						}
					} else {
						alarm = false;
					}
				}
			});
			port.notifyOnDataAvailable(true);

			// musimy odczekać tak średnio ponad sekundę żeby port chwycił
			Thread.sleep(1500);

		} catch (NoSuchPortException e) {
			e.printStackTrace();
		} catch (PortInUseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UnsupportedCommOperationException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (TooManyListenersException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Włącza lub wyłącza światł o identyfikatorze li.
	 * 
	 * @param li
	 *            identyfikator światła typu enum Light
	 */
	public void toogleLight(Light li) {
		try {
			switch (li) {
			case ROOM_LIGHT:
				output.write('5');
				break;
			case KITCHEN_LIGHT:
				output.write('6');
				break;
			case BATHROOM_LIGHT:
				output.write('7');
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Ustawia linijkę świetlną na zadany poziom świcenie
	 * 
	 * @param i
	 *            stan linijki, możliwe wartości {0,1,2,3,4}
	 */
	public void setLine(int i) {
		try {
			if (i >= 0 && i <= 4) {
				output.write(Character.forDigit(i, 10));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Zwraca stan alarmu
	 * @return true - alarm włączony, false - alarm wyłączony
	 */
	public boolean getAlarm(){
		return alarm;
	}

	public void close() {
		port.close();
	}
}
